/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.jomijushi.fid.dao;

import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author jcgrados
 */
public  class JpaDao<K, E> implements DAO<K, E> {

	protected Class<E> entityClass;   
	@PersistenceContext
	protected EntityManager entityManager;  
    @PersistenceContext
    protected EntityManagerFactory emf = null;

    public JpaDao() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
        this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
    }

    
    public JpaDao(int a) {        
		Class<? extends JpaDao> genericSuperclass = getClass();
    }


    public void setEntityClass(Class<E> e){
        this.entityClass = e;
    }



    public EntityManager getEntityManager() {
        return this.entityManager;
    }

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public void persist(E entity) {
        entityManager.persist(entity);
    }

    public void merge(E entity) { 
         entityManager.merge(entity);
    }

    public void remove(E entity) { 
        entityManager.remove(entityManager.merge(entity));
    }

    public E findById(K id) {
        return entityManager.find(entityClass, id);
    }

    public E findById(Class<E> e, K id) {
        return entityManager.find(e, id);
    }


    public E buscar(String keyword, Object valorKey)
    {
        String nombreClase = entityClass.getSimpleName();
        String jpql="SELECT t FROM "+nombreClase+" t WHERE t."+keyword+" = :keyword";

        try {
            return (E)entityManager.createQuery(jpql).setParameter("keyword", valorKey).getSingleResult();
        }
        catch(Exception e){
            System.out.println("jpql ejecutado = "+jpql);
            System.out.println("DAO Error: no se realiza la busqueda correctamente: "+e.getLocalizedMessage()+"\n"+e.getCause().toString());
            return null;
        }
    }

    public E buscar(String nombreHijo, String keyword, Object valorKey)
    {
        String nombreClase = entityClass.getSimpleName();
        //String sql="SELECT t FROM "+nombreHijo+" t WHERE t."+keyword+"= :keyword";
        String jpql="SELECT t FROM "+nombreClase+" t WHERE t."+nombreHijo+"."+keyword+"= :keyword";

        try {
            return (E)entityManager.createQuery(jpql).setParameter("keyword", valorKey).getSingleResult();
        }
        catch(Exception e){
            System.out.println("jpql ejecutada = "+jpql);
            System.out.println("DAO Error: no se realiza la busqueda correctamente: "+e.getLocalizedMessage()+"\n"+e.getCause().toString());
            return null;
        }
    }




    public List<E> reportar(String keyword, Object valorKey, String ordenarBy, String criterioOrden, boolean verTodo, boolean isLike, int limInf, int limSup) {
        
        if(criterioOrden.compareTo("")==0 || (criterioOrden.compareToIgnoreCase("asc")!=0 && criterioOrden.compareToIgnoreCase("desc")!=0))
           criterioOrden = "asc";
        if(ordenarBy.compareTo("")==0)
           ordenarBy = keyword;

        String jpql="";
        Query query=null;
        String nameClase = entityClass.getSimpleName();


        if(valorKey!=null || keyword.compareToIgnoreCase("")!=0){
            jpql = "select p from "+nameClase+" p where p."+keyword;
            if(isLike)
               jpql+= " like :keyword ";
            else
               jpql+= " = :keyword ";
         }
         else
            jpql = "select p from "+nameClase+" p ";

        if(ordenarBy.compareToIgnoreCase("")!=0)
            jpql+=" order by p."+ordenarBy+"  "+criterioOrden;
         

           
            try{
                query = entityManager.createQuery(jpql);                
                if(valorKey!=null){
                    if(isLike)                  
                        query.setParameter("keyword", "%"+valorKey+"%");                    
                    else
                        query.setParameter("keyword",valorKey);                    
                }

                if(!verTodo){// esto nos permitira hacer una paginación
                    query.setMaxResults(limSup);
                    query.setFirstResult(limInf);
                }
                List<E> lista = query.getResultList();
                return lista;
            }
            catch(Exception e){
                System.out.println("jpql ejecutado = "+jpql);
                System.out.println("DAO Error: No se realiza la jpql de manera correcta\n"+e.getCause().toString()+"\n"+e.getMessage());
            }        
        //devolvemos lista vacia
        List<E> lstE = new ArrayList<E>();
        return lstE;
    }



    public List<E> reportar(String nombreHijo, String keyword, Object valorKey, String ordenarBy, String criterioOrden, boolean verTodo, boolean isLike, int limInf, int limSup) {

        if(criterioOrden.compareTo("")==0 || (criterioOrden.compareToIgnoreCase("asc")!=0 && criterioOrden.compareToIgnoreCase("desc")!=0))
           criterioOrden = "asc";
        if(ordenarBy.compareTo("")==0)
           ordenarBy = keyword;

        String jpql="";
        Query query = null;           

        if(keyword.compareToIgnoreCase("")!=0){
           if(valorKey!=null){                    
              jpql = "select p from "+nombreHijo+" p where p."+keyword;
              if(isLike)
                 jpql+= " like :keyword ";
              else
                 jpql+= " = keyword";

              jpql+=" order by p."+ordenarBy+"  "+criterioOrden;
            }
          else
                 jpql = "select p from "+nombreHijo+" p order by p."+ordenarBy+"  "+criterioOrden;                
        }
        else{
             if(ordenarBy.compareToIgnoreCase("")==0)
                jpql = "select p from "+nombreHijo+" p ";
             else
                    jpql = "select p from "+nombreHijo+" p order by p."+ordenarBy+"  "+criterioOrden;
         }
          
        try{            
             query = entityManager.createQuery(jpql);
             if(valorKey!=null){                   
                if(isLike)
                    query.setParameter("keyword", "%"+valorKey+"%");
                else
                    query.setParameter("keyword", valorKey);
             }

             if(!verTodo){// esto nos permitira hacer una paginación
                    query.setMaxResults(limSup);
                    query.setFirstResult(limInf);
             }
             List<E> lista = query.getResultList();
             return lista;
         }
         catch(Exception e){
                System.out.println("jpql ejecutado = "+jpql);
                System.out.println("DAO Error: No se realiza la jpql de manera correcta\n"+e.getCause().toString()+"\n"+e.getMessage());
            }           
      
        //devolvemos lista vacia
        List<E> lstE = new ArrayList<E>();
        return lstE;
    }


}
